Texture2D gTexture;

float BloomIntensity = 1.1f;
 
float OriginalIntensity = 1.0;

SamplerState samLinear
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Clamp;
    AddressV = Clamp;
};

DepthStencilState NoDepth
{
	DepthEnable = TRUE;
};

RasterizerState BackCulling 
{ 
	CullMode = BACK; 
};

struct VS_INPUT_STRUCT
{
    float3 Pos : POSITION;
	float2 TexCoord : TEXCOORD0;

};
struct PS_INPUT_STRUCT
{
    float4 Pos : SV_POSITION;
	float2 TexCoord : TEXCOORD1;
};

PS_INPUT_STRUCT VS(VS_INPUT_STRUCT input)
{
	PS_INPUT_STRUCT output = (PS_INPUT_STRUCT)0;
	// Set the Position
	output.Pos = float4(input.Pos, 1.0f);
	// Set the Text coord
	output.TexCoord = input.TexCoord;
	return output;
}

float4 CreateBloom( float4 color)
{	
	float4 bloom;
	bloom.r = (color.x - 0.5f) / (1-0.5f);
	bloom.g = (color.y - 0.5f) / (1-0.5f);
	bloom.b = (color.z - 0.5f) / (1-0.5f);
	bloom.a = 1;


	bloom = saturate(bloom);
	return bloom;
}

float4 PS(PS_INPUT_STRUCT input):SV_TARGET
{
	float4 bloomColor =  gTexture.Sample( samLinear, input.TexCoord );
	bloomColor = CreateBloom( bloomColor);

	///BLUR
	///***
	uint height = 600;
	uint width = 800;
	gTexture.GetDimensions( width, height );
	// Step 2: calculate dx and dy
	float dx = 1.0f/width;
	float dy = 1.0f/height;
	
	// Step 3: Create a double for loop (5 iterations each)
	//		   Inside the look, calculate the offset in each direction. Make sure not to take every pixel but move by 2 pixels each time
	//			Do a texture lookup using your previously calculated uv coordinates + the offset, and add to the final color
	float2 texCoord;
	texCoord.x = input.TexCoord.x - dx*2;
	texCoord.y = input.TexCoord.y - dy*2;

	for (int i = 0; i < 3; ++i)
	{
		for (int j = 0; j < 3; ++j)
		{
			bloomColor += CreateBloom(  gTexture.Sample( samLinear, texCoord ) );
			texCoord.x += dx;
		}
		texCoord.x = input.TexCoord.x - dx*2;
		texCoord.y += dy;
	}

	// Step 4: Divide the final color by the number of passes (in this case 5*5)
	float3 mean = float3(bloomColor.r/(3*3), bloomColor.g/(3*3), bloomColor.b/(3*3));
	///***

	float4 originalColor =  gTexture.Sample( samLinear, input.TexCoord );

	bloomColor *= BloomIntensity;
	originalColor *= OriginalIntensity;

	originalColor *= 1 - saturate(bloomColor);
	float4 color = originalColor + bloomColor;
	return float4(color.rgb,1);
}

technique11 Bloom
{
    pass P0
    {
		// Set states
		SetRasterizerState(BackCulling);
		SetDepthStencilState(NoDepth,0);
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}